package com.forg.mvc.core.common.groovy;

import java.io.File;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.Script;


public class GroovyCompiler {
    
    
    private static final Logger logger = LoggerFactory.getLogger(GroovyCompiler.class);
    
    private static Map<String, GroovyClass> groovyCaches      = new ConcurrentHashMap<String, GroovyClass>();

    private static ClassLoader cl = GroovyCompiler.class.getClassLoader();  
    private static  GroovyClassLoader groovyCl = new GroovyClassLoader(cl);  
    
    public static GroovyClass getClass(File script){
        
        if(script == null || !script.exists()){
            return null;
        }
        
        try {
            
            String fileName = script.getPath() ;
            GroovyClass groovyClazz = groovyCaches.get(fileName);
            
            //cached,check if modified 
            if(groovyClazz != null){
                long lastModified = script.lastModified();
                
                //newest
                if(lastModified <= groovyClazz.getLastmodified() ){
                    logger.debug("[{}]hit cache.",fileName);
                    return groovyClazz;
                }
                
                //update cache
                groovyClazz = null;
            }
            
            //need new a Instance
            //not use GroovyClassLoader cache
            Class<?> groovyClass = groovyCl.parseClass(new GroovyCodeSource(script, "UTF-8"),false);  
            groovyClazz = new GroovyClass((Script)groovyClass.newInstance(),script.lastModified());
            
            logger.debug("[{}]update cache.",fileName);
            groovyCaches.put(fileName, groovyClazz);
            
            return groovyClazz;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static GroovyClass getClass(URL script){
        
        return getClass(new File(script.getFile()));
    }
    
    public static GroovyClass getClass(String script){
        
        return getClass(cl.getResource(script));
    }
    
        
}
